import 'dart:typed_data';

class ByteBuilder {
  ByteData _byteData = ByteData(0);
  int _offset = 0;

  void addUint8(int value) {
    // Ensure the value is within the valid range for a Uint8
    if (value < 0 || value > 255) {
      throw RangeError.range(value, 0, 255, "value");
    }
    _ensureCapacity(1);
    _byteData.setUint8(_offset, value);
    _offset += 1;
  }

  void addUint16(int value, [Endian endian = Endian.little]) {
    // Ensure the value is within the valid range for a Uint16
    if (value < 0 || value > 65535) {
      throw RangeError.range(value, 0, 65535, "value");
    }
    _ensureCapacity(2);
    _byteData.setUint16(_offset, value, endian);
    _offset += 2;
  }

  void addUint32(int value, [Endian endian = Endian.little]) {
    // Ensure the value is within the valid range for a Uint32
    if (value < 0 || value > 4294967295) {
      throw RangeError.range(value, 0, 4294967295, "value");
    }
    _ensureCapacity(4);
    _byteData.setUint32(_offset, value, endian);
    _offset += 4;
  }

  void addUint64(int value, [Endian endian = Endian.little]) {
    // Ensure the value is within the valid range for a Uint64
    if (value < 0) {
      throw RangeError.value(value, "value", "Must be non-negative");
    }
    _ensureCapacity(8);
    _byteData.setUint64(_offset, value, endian);
    _offset += 8;
  }

  void addBytes(Uint8List bytes) {
    _ensureCapacity(bytes.length);
    for (int i = 0; i < bytes.length; i++) {
      _byteData.setUint8(_offset + i, bytes[i]);
    }
    _offset += bytes.length;
  }

  void _ensureCapacity(int additionalBytes) {
    if (_offset + additionalBytes > _byteData.lengthInBytes) {
      // 计算新的容量（使用2倍增长策略）
      final newCapacity = (_offset + additionalBytes) * 2;
      final newData = ByteData(newCapacity);

      // 复制旧数据到新缓冲区
      for (int i = 0; i < _offset; i++) {
        newData.setUint8(i, _byteData.getUint8(i));
      }

      // ✅ 关键：更新 _byteData 引用
      _byteData = newData;
    }
  }

  Uint8List toBytes() {
    return _byteData.buffer.asUint8List(0, _offset);
  }
}
